#include <iostream>

/**
 * C++
 *
 * 引用变量是一个别名，也就是说，它是某个已经存在变量的另一个名字，一旦、把引用初始化为某个变量，就可以使用
 * 改引用名称或变量名称來指向变量。
 *
 * 引用必须在定义时初始化，并且一旦绑定到一个变量后，就不能再绑定到其他变量。
 *
 * int a = 10;
 * int &ref = a; //ref 就是 a的引用
 *
 * int &ref 表示ref是一个int类型的引用。
 * ref是a的别名，对ref的操作会直接作用于a
 *
 */
int main() {

    /**
     * C++ 引用 vs 指针
     *
     * 不存在空引用，引用必须连接到一块合法的内存。
     * 一旦引用被初始化为一个对象，就不能被指向到另一个对象吗。指针可以在任何时候指向另一个对象。
     * 引用必须在创建时被初始化。指针在任何时间被初始化。
     * 引用的对象必须是一个变量，而指针必须是一个地址。
     * 不能创建引用数组，但是可以已创建数组的引用(引用不能为空，必须是一个一个变量)
     *
     *  特性                      引用                          指针
     *
     *  定义和初始化              必须初始化，不能为NULL           可以不初始化，可以为NULL
     *  语法                     使用&，例如 int &ref = a        使用*申明，例如int *ptr = &a;
     *  重新绑定                  不能重新绑定，一旦初始化后
     *                           始终引用一个对象。              可以重新指向其他的对象，例如ptr=&b
     *
     *  空值                      不能为NULL                    可以为NULL
     *  内存占用                  不占用额外内存                 占用额外内存
     *  访问方式                  ref = 10                      *ptr = 10;
     *  多级间接访问              不支持多级间访问               支持多级间访问
     *  函数参数传递              void fun(int &x){x = 10};     void fun(int *x){*x =10};
     *  数组与引用                int (&ref)[10] = arr;         int *ptr[10];
     *  安全性                   更安全                         更灵活，但是容易出错（空指针，野指针）
     *  底层实现                 通常指针实现，但是编译器会优先作为 直接存储目标对象的内存地址
     *                          直接操作的引用的对象
     */

    //声明简单的变量
    int     i;
    double  d;

    //声明引用变量
    int &r = i;
    double &s = d;

    i = 5;
    std::cout << "Value of i : " << i << std::endl;
    std::cout << "Value of i reference : " << r << std::endl;

    d  = 11.7;
    std::cout << "Value of d : " << d << std::endl;
    std::cout << "Value of d reference : " << d << std::endl;

    return 0;
}
